<?php


namespace yy\helper;

class Upload
{
    protected $fileSize = 1024 * 1024 * 50;
    protected $fileExt = ['jpg', 'jpeg', 'png','gif','docx','doc','xlsx','xls','zip','rar','7z' ,'mp4','mp3','wma','wmv','mov','wav'];
    protected $fileName = 'image';
    protected $saveName = [];
    protected $diskName = 'local';
    protected $putPath = '';
    protected $errMsg = '';

    /**
     * 上传文件
     * @param string $fileName 上传文件名
     * @param string $diskName 磁盘配制名称
     * @param string $putPath 保存文件夹
     * @param string $size 大小
     * @param string $ext 扩展名
     * @return array|mixed
     */
    public function upFile($fileName = 'file' , $diskName = '' , $putPath = '' , $size = '' , $ext = '')
    {
        $this->fileName = $fileName;
        if ($diskName){
            $this->diskName = $diskName;
        }
        if ($putPath){
            $this->putPath = $putPath;
        }
        if ($size){
            $this->fileSize = $size;
        }
        if ($ext){
            $this->fileExt = $ext;
        }
        $this->_upload();
        if ($this->errMsg){
            return $this->_error();
        }

        return $this->saveName[0];
    }


    /**
     * 上传图片
     * @param string $fileName 上传文件名
     * @param string $diskName 磁盘配制名称
     * @param string $putPath 保存文件夹
     * @param bool $compress 是否压缩
     * @param string $size 大小
     * @param string $ext 扩展名
     * @return array|mixed
     */
    public function upImage($fileName = 'pic' , $diskName = '' , $putPath = '' , $compress = true , $size = '' , $ext = '')
    {
        $this->fileName = $fileName;
        if ($diskName){
            $this->diskName = $diskName;
        }
        if ($putPath){
            $this->putPath = $putPath;
        }
        if ($size){
            $this->fileSize = $size;
        }
        $ext = $ext ?: ['jpg', 'jpeg', 'png','gif'];
        if ($ext){
            $this->fileExt = $ext;
        }
        $this->_upload();
        if ($this->errMsg){
            return $this->_error();
        }
        if ($compress !== true)
            return $this->saveName[0];

        return $this->imageThumb($this->saveName[0]);
    }

    /**
     * 压缩图片
     * @param $path
     * @return mixed
     */
    public function imageThumb($path)
    {
        $saveName = $path;
        $end = strrchr( $saveName , ".");
        $new_path = str_replace($end , "_thumb" . $end , $saveName);

        $image = \think\Image::open('.' .$saveName);
        $image->thumb(750, 750)->save('.' .$new_path);

        return $new_path;
    }
    /**
     * 文件base64上传
     * @param $imgbase64  base64
     * @param $filesystem 文件保存路径 为了和上边上传保持一致
     * @param $folder 文件保存路径 为了和上边上传保持一致
     * @return array|bool
     */
    public function base64Upload($imgbase64, $filesystem, $folder)
    {
        //图片上传
        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $imgbase64, $result)) {
            $ext = $result[2];//图片后缀
            $new_file = config("filesystem.disks.{$filesystem}.root") . '/'  . $folder . '/' . date('Ymd/');
            if (!file_exists($new_file)) {
                //检查是否有该文件夹，如果没有就创建，并给予最高权限
                mkdir($new_file, 0777, true);
            }

            $filename = time() . '_' . uniqid() . ".{$ext}"; //文件名
            $new_file = $new_file . $filename;
            //写入操作

            if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $imgbase64)))) {
                $size = filesize($new_file);
                $new_file = str_replace(config("filesystem.disks.{$filesystem}.root") , config("filesystem.disks.{$filesystem}.url") , $new_file);
                return str_replace('./' , '/' , $new_file);


            }
        }
        $this->errMsg = '上传文件失败';
        return $this->_error();
    }

    /**
     * base64转二进制
     * @param $base64
     * @return array
     */
    public function base64ToBinary($base64)
    {
        //判断是否有逗号
        if (strstr($base64, ",")) {
            $base64 = explode(',', $base64);
            $base64 = $base64[1];
        }
        //var_dump($base64);
        $binary = base64_decode($base64);
        if (!$binary) {
            return $this->setErr(504, 'base64解析出错');
        }
        $type = $this->getFileType($binary);
        return [
            'binary' => $binary,
            'type' => $type,
        ];
    }

    /**
     * 根据二进制编码返回文件类型
     * @param Binary $bin 文件内容
     * @return string
     */
    public function getFileType($bin)
    {
        $bin            = substr($bin, 0, 2);
        $strInfo        = @unpack("C2chars", $bin);
        $typeCode       = intval($strInfo['chars1'] . $strInfo['chars2']);
        $this->typeCode = $typeCode;
        switch ($typeCode) {
            case 7790:
                $fileType = 'exe';
                break;
            case 7784:
                $fileType = 'midi';
                break;
            case 8297:
                $fileType = 'rar';
                break;
            case 255216:
                $fileType = 'jpg';
                break;
            case 7173:
                $fileType = 'gif';
                break;
            case 6677:
                $fileType = 'bmp';
                break;
            case 13780:
                $fileType = 'png';
                break;
            case 208207:
                $fileType = 'office2003';
                break;
            case 8075:
                $fileType = 'office2007';
                break;
            default:
                $fileType = 'unknown';
        }
        return $fileType;
    }

    /**
     * 文件上传
     * @return string
     */
    protected function _upload(){
        // 获取表单上传文件
        $files = request()->file();
        if (empty($files))return $this->errMsg = '请选择上传文件';
        // 上传验证
        $rule = [
            $this->fileName => [
                'filesize' => $this->fileSize ,
                'fileExt' => $this->fileExt
            ]
        ];
        $message = [
            $this->fileName => [
                'filesize' => '文件大小不符合' ,
                'fileExt' => '文件类型不符合'
            ]
        ];
        try {
            // 上传验证
            validate($rule  , $message)
                ->check($files);
            // 计算存储路径
            if (empty($this->putPath)){
                $this->putPath = $this->fileName;
            }
            // 计算访问路径
            if ($this->diskName == 'local') {
                $prePath = '/runtime/storage/';
            } else {
                $prePath = \think\facade\Filesystem::getDiskConfig($this->diskName,'url') . '/';
            }
            // 文件上传
            foreach ($files as $file) {

                $saveName = $prePath .\think\facade\Filesystem::disk($this->diskName)->putFile($this->putPath, $file);
                $this->saveName[] = str_replace("\\", '/', $saveName);
            }
        } catch (\think\exception\ValidateException $e) {
            $this->errMsg = $e->getMessage();
        }
    }

    /**
     * 返回错误信息
     * @return array
     */
    protected function _error()
    {
        return [
            'error' => 1,
            'msg' => $this->errMsg
        ];

    }


}